package com.laoxu.test.rbacdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.laoxu.test.rbacdemo.common.PageRequest;
import com.laoxu.test.rbacdemo.dao.SysRoleMenuMapper;
import com.laoxu.test.rbacdemo.model.SysRole;
import com.laoxu.test.rbacdemo.dao.SysRoleMapper;
import com.laoxu.test.rbacdemo.model.SysRoleMenu;
import com.laoxu.test.rbacdemo.service.SysRoleMenuService;
import com.laoxu.test.rbacdemo.service.SysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.laoxu.test.rbacdemo.service.SysUserRoleService;
import com.laoxu.test.rbacdemo.service.UserManager;
import com.laoxu.test.rbacdemo.util.SortUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author laoxu
 * @since 2020-08-09
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleMenuService sysRoleMenuService;
    @Autowired
    private UserManager userManager;

    @Override
    public IPage<SysRole> findRoles(SysRole role, PageRequest request) {
        try {
            LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();

            if (StringUtils.isNotBlank(role.getRoleName())) {
                queryWrapper.eq(SysRole::getRoleName, role.getRoleName());
            }
            
            Page<SysRole> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            return this.page(page,queryWrapper);
        } catch (Exception e) {
            log.error("获取角色信息失败", e);
            return null;
        }
    }

    @Override
    public List<SysRole> findUserRole(String userName) {
        return baseMapper.findUserRole(userName);
    }

    @Override
    public SysRole findByName(String roleName) {
        return baseMapper.selectOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleName, roleName));
    }

    @Override
    public void createRole(SysRole role) {
        role.setCreateTime(new Date());
        this.save(role);

        String[] menuIds = role.getMenuId().split(StringPool.COMMA);
        setRoleMenus(role, menuIds);
    }

    @Override
    public void deleteRoles(String[] roleIds) throws Exception {
        // 查找这些角色关联了那些用户
        List<String> userIds = this.sysUserRoleService.findUserIdsByRoleId(roleIds);

        List<String> list = Arrays.asList(roleIds);

        baseMapper.deleteBatchIds(list);

        this.sysRoleMenuService.deleteRoleMenusByRoleId(roleIds);
        this.sysUserRoleService.deleteUserRolesByRoleId(roleIds);
    }

    @Override
    public void updateRole(SysRole role) throws Exception {
        // 查找这些角色关联了那些用户
        String[] roleId = {String.valueOf(role.getRoleId())};
        List<String> userIds = this.sysUserRoleService.findUserIdsByRoleId(roleId);

        role.setUpdateTime(new Date());
        baseMapper.updateById(role);

        sysRoleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getRoleId()));

        String[] menuIds = role.getMenuId().split(StringPool.COMMA);
        setRoleMenus(role, menuIds);

    }

    private void setRoleMenus(SysRole role, String[] menuIds) {
        Arrays.stream(menuIds).forEach(menuId -> {
            SysRoleMenu rm = new SysRoleMenu();
            rm.setMenuId(Long.valueOf(menuId));
            rm.setRoleId(role.getRoleId());
            this.sysRoleMenuMapper.insert(rm);
        });
    }
}
